package com.kl.modular.base.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.kl.modular.base.service.util.Underline2CamelUtil;
import com.kl.modular.base.service.api.IBaseService;

import java.io.Serializable;
import java.util.*;

/**
 *
 * 公用SERVICE实现类
 *
 * 1、继承mybatis-plus 再行封装公用方法
 * 2、所有SERVICE需继承该类
 *
 * @author xr_zjb
 * @date 2017/06/07 09:50
 *
 */
public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements IBaseService<T> {


    public Map genUnderLine(Map paramMap){
        if(paramMap == null){
            return null;
        }
        Map columnMap = new HashMap();
        for(Object column: paramMap.keySet()){
            if(!(column instanceof String)){
                continue;
            }
            Object datas = paramMap.get(column);
            String colmns = Underline2CamelUtil.camel2Underline((String)column);
            columnMap.put(colmns, datas);
        }
        return columnMap;
    }

    public Map getUnderLineMap(T entity){
        String jsonstr = JSON.toJSONString(entity);
        Map paramMap = JSON.parseObject(jsonstr);
        return genUnderLine(paramMap);
    }

    public Map getUnderLineMapByObj(Object entity){
        String jsonstr = JSON.toJSONString(entity);
        Map paramMap = JSON.parseObject(jsonstr);
        return genUnderLine(paramMap);
    }


    /**
     * 查询列表数据
     * @param entity 对象数据PO类
     * @return
     */
    public List<T> selectListByEntity(T entity) {
        if(entity == null){
            return Collections.EMPTY_LIST;
        }
        Map paramMap = getUnderLineMapByObj(entity);
        Wrapper<T> wrapper = new EntityWrapper<T>();
        wrapper.allEq(paramMap);
        List<T> list = selectList(wrapper);
        return list;
    }

    /**
     * 查询列表数据
     * @param bo bo
     * @return
     */
    public List<T> selectListByBo(Object bo) {
        T entity = (T) JSON.parseObject(JSON.toJSONString(bo));
        return selectListByEntity(entity);
    }

    /**
     * 查询对象数据One
     * @param entity
     * @return
     */
    public T selectOneByEntity(T entity){
        if(entity == null){
            return null;
        }
        Map paramMap = getUnderLineMapByObj(entity);
        Wrapper<T> wrapper = new EntityWrapper<T>();
        wrapper.allEq(paramMap);
        T t = selectOne(wrapper);
        if(t == null){
            return null;
        }
        return t;
    }

    /**
     * 查询对象数据One
     * @param bo
     * @return
     */
    public T selectOneByBo(Object bo) {
        T entity = (T) JSON.parseObject(JSON.toJSONString(bo));
        return selectOneByEntity(entity);
    }

    /**
     * 查询对象列表数据
     * @param wrapper
     * @return
     */
    public List<T> selectListByWrapper(Wrapper<T> wrapper) {
        return selectList(wrapper);
    }

    /**
     * 查询一个对象数据
     * @param wrapper
     * @return
     */
    public T selectOneByWrapper(Wrapper<T> wrapper) {
        List<T> selectList = selectListByWrapper(wrapper);
        if(selectList == null || selectList.size() == 0){
            return null;
        }
        return selectList.get(0);
    }

    /**
     * 查询对象数据分页
     * @param page 分页数据
     * @param entity 对象数据PO类
     * @return
     */
    public Page<T> selectPageByEntity(Page<T> page, T entity) {
        if(page == null)page = new Page<T>();
        if(entity == null)return page;
        Map paramMap = getUnderLineMapByObj(entity);
        Wrapper<T> wrapper = new EntityWrapper<T>();
        wrapper.allEq(paramMap);
         Page<T> queryPage = selectPage(page, wrapper);
        return queryPage;
    }

    /**
     * 查询对象数据分页
     * @param page 分页数据
     * @param bo 对象数据Bo类
     * @return
     */
    public Page<T> selectPageByBo(Page<T> page, Object bo) {
        T entity = (T) JSON.parseObject(JSON.toJSONString(bo));
        return selectPageByEntity(page, entity);
    }

    /**
     * 逻辑删除
     * @param id 主键ID
     */
    public void logicalDelete(Serializable id) {
        if(id == null){
            return;
        }
        HashMap<String, Object> entityMap = new HashMap<String, Object>();
        entityMap.put("id", id);
        entityMap.put("enabled", true);
        T entity = (T) JSON.parse(JSON.toJSONString(entityMap));
        if(entity == null) return;
        super.updateById(entity);
    }

    /**
     * 批量逻辑删除
     * @param idList
     */
    public void logicalDeleteBatch(List<Serializable> idList) {
        if(idList == null || idList.size() == 0)return;
        List<T> entityList = new ArrayList<T>();
        for(Serializable id :idList){
            HashMap<String, Object> entityMap = new HashMap<String, Object>();
            entityMap.put("id", id);
            entityMap.put("enabled", true);
            T entity = (T) JSON.parse(JSON.toJSONString(entityMap));
            entityList.add(entity);
        }
        updateBatchById(entityList);
    }

    /**
     * 批量逻辑删除
     * @param ids ids字符串
     */
    public void logicalDeleteBatch(String[] ids) {
        List<Serializable> idList = new ArrayList<Serializable>();
        Collections.addAll(idList, ids);
        logicalDeleteBatch(idList);
    }

    /**
     * 物理删除数据
     * @param entity 对象数据PO
     */
    public void deleteByEntity(T entity) {
        if(entity == null)return;
        Map map = getUnderLineMap(entity);
        deleteByMap(map);
    }

    /**
     * 记录数
     * @param entity 对象数据PO
     * @return
     */
    public int selectCountByEntity(T entity) {
        Map paramMap = getUnderLineMapByObj(entity);
        Wrapper<T> wrapper = new EntityWrapper<T>();
        wrapper.allEq(paramMap);
        int result = selectCount(wrapper);
        return result;
    }


}
